import { EnumBjlResult } from "@/models/enums/EnumBjlResult";
import { ExcutePlan, RecmInfo, RoundInfo } from "../ExecutePlan";
import { FixedStrategy } from "../recmStrategy/FixedStrategy";
import { WinRabbitMoneyStrategy } from "./WinRabbitMoneyStrategy";
import { IMoneyStrategy } from "../IMoneyStrategy";
import { IPlan } from "../IExecutePlan";
import { IGroupMoneyOption, NormalGroupMoneyStrategy } from "./NormalGroupMoneyStrategy";


export interface IGroupMoneyOptionV2 extends IGroupMoneyOption {
    maxLevel: number;
}
export class WisdomGroupMoneyStrategyV2 implements IMoneyStrategy {
    option: IGroupMoneyOptionV2;
    strategyName: string = "";
    debugCompoenent: string = "WisdomMoneyStrategyV2Debug";
    groupResultArray: number[] = [];
    levelArray: number[] = [];
    prevMoney: number = 0;
    currentRecmMoney: number = 0;
    allResultArray: number[] = [];
    start: boolean = true;
    extendCount: number = 0;
    stopPosition: number | null = null;
    levelChange: boolean = false;
    recmV: EnumBjlResult = EnumBjlResult.U;


    constructor(name?: string, option?: IGroupMoneyOptionV2) {
        this.strategyName = name ?? "GroupMoneyStrategy" + (new Date()).getMilliseconds() + parseInt((Math.random() * 1000).toString());
        this.start = true;
        this.extendCount = 0;
        this.levelArray = [];
        this.currentRecmMoney = 0;
        this.prevMoney = 0;
        this.allResultArray = [];
        this.groupResultArray = [];
        this.extendCount = 0;
        this.stopPosition = null;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                groupCount: 12,
                addStep: 100,
                devideStep: 100,
                reverse: false, //true:赢了+100，输了-100
                maxLevel: 1000,
            }
        }
        this.resetStrategy();
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.currentRecmMoney];
    }
    resetRecm(): void {
        this.resetStrategy();
    }
    copyValue(valueObj: any): void {
        let obj = valueObj as WisdomGroupMoneyStrategyV2
        if (obj) {
            this.debugCompoenent = obj.debugCompoenent;
            Object.assign(this.option, obj.option);
            this.groupResultArray = obj.groupResultArray;
            this.levelArray = obj.levelArray;
            this.allResultArray = obj.allResultArray;
            this.currentRecmMoney = obj.currentRecmMoney;
            this.prevMoney = obj.prevMoney;
            this.start = obj.start;
            this.extendCount = obj.extendCount;
            this.stopPosition = obj.stopPosition;
            this.recmV = obj.recmV;
        }
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {

        let recmV = userRecm.recmV;
        this.levelChange = false;
        let recmMoney = this.currentRecmMoney < baseMoney ? baseMoney : this.currentRecmMoney;
        if (!this.start) {
            return [EnumBjlResult.U, recmMoney];
        }

        let divided = false;
        if ((recmInfo.betCount) % this.option.groupCount == 0 && recmInfo.betCount > 0 && recmInfo.betCount != recmInfo.preBetCount) {

            let diff = recmInfo.roundSummaryInfo.winCount - recmInfo.roundSummaryInfo.failCount;


            let prev: number = 0;
            if (this.levelArray.length > 0) {
                prev = Math.abs(this.levelArray[this.levelArray.length - 1]);
            }

            this.groupResultArray.push(diff);
            this.allResultArray.push(diff);
            let csum = this.groupResultArray.reduce((prev, curr) => prev + curr, 0);

            if (diff > 0 && csum > 0 && csum >= prev) {
                if (this.levelArray[this.levelArray.length - 1] < 0) {
                    while (csum >= prev) {
                        if (prev > 0) {
                            if (this.extendCount <= 1) {
                                let step = this.option.devideStep;
                                recmMoney += step;
                                this.groupResultArray = [];
                                this.levelArray.pop();
                                this.extendCount = 0;
                            }
                            else {
                                divided = true;
                                this.groupResultArray = [];
                                this.levelArray.pop();
                                this.extendCount--;
                            }
                        }
                        csum = csum - prev;
                        if (this.levelArray.length > 0) {
                            prev = Math.abs(this.levelArray[this.levelArray.length - 1]);
                        }
                        else {
                            prev = 0;
                            break;
                        }

                    }
                    if (csum > 0 && this.levelArray.length > 0) {
                        this.levelArray[this.levelArray.length - 1] += csum;
                    }
                    else if (csum != 0) {
                        this.levelArray.push(csum);
                    }

                    this.groupResultArray = [];
                }
                else {

                }
                // if (prev > 0) {
                //     if (this.extendCount <= 0) {
                //         let step = this.option.devideStep;
                //         recmMoney += step;
                //         this.groupResultArray = [];
                //         this.levelArray.pop();
                //     }
                //     else {
                //         divided = true;
                //         this.groupResultArray = [];
                //         this.levelArray.pop();
                //         this.extendCount--;
                //     }
                // }

            }
            else if (diff > 0 && csum < 0) {
                let step = this.option.addStep;
                recmMoney += step;
                if (recmMoney >= this.option.maxLevel) {
                    recmMoney = this.option.maxLevel;
                    this.extendCount++;
                }
                this.groupResultArray = [];
                this.levelArray.push(csum);
            }
            else {
            }


            recmInfo.resetRoundSummaryInfo();
            userRecm.resetRoundSummaryInfo();
        }
        if (recmMoney < baseMoney) {
            recmMoney = baseMoney;
        }

        this.prevMoney = this.currentRecmMoney;
        this.currentRecmMoney = recmMoney;
        this.recmV = recmV;
        if (this.prevMoney != this.currentRecmMoney && this.prevMoney > 0) {
            this.levelChange = true;
        }
        else {
            this.levelChange = false;
        }
        return [recmV, recmMoney];
    }
    resetStrategy() {
        this.groupResultArray = [];
        this.levelArray = [];
        this.allResultArray = [];
        this.currentRecmMoney = 0;
        this.prevMoney = 0;
        this.start = true;
        this.extendCount = 0;
        this.stopPosition = null;
        this.levelChange = false;
        this.recmV = EnumBjlResult.U;
    }
    getLevel() {
        return this.levelArray.length;
    }
    isResume() {
        return this.currentRecmMoney < this.option.maxLevel;
    }
    restart() {
        this.start = true;
    }
    stop() {

        this.stopPosition = this.getSum();
        this.start = false;
    }
    isStart() {
        return this.start;
    }
    getSum() {
        let levelSum = this.levelArray.reduce((prev, curr) => prev + curr, 0);
        let groupSum = this.groupResultArray.reduce((prev, curr) => prev + curr, 0);
        return levelSum + groupSum;
    }
}

export class WisdomMoneyStrategyV2 implements IMoneyStrategy {
    subPlan: IPlan[];
    debugCompoenent: string = "WisdomMoneyStrategyV2Debug";
    strategyName: string;
    startIndex: number = -1;
    startLevel: number = 1000;
    constructor(name?: string) {
        this.strategyName = name ?? "GroupMoneyStrategy" + (new Date()).getMilliseconds() + parseInt((Math.random() * 1000).toString());
        this.subPlan = [];
        this.resetStrategy();
    }
    showMoney(): [EnumBjlResult, number] {
        throw new Error("Method not implemented.");
    }
    resetRecm() {
        this.subPlan.forEach(item => item.resetRecm());
    }
    resetStrategy(): void {
        //正向，兔子算法
        let f_rabbit_plan = new ExcutePlan();
        f_rabbit_plan.planName = "正向兔子";
        f_rabbit_plan.recmStrategy = [new FixedStrategy({ reverse: false })]
        f_rabbit_plan.moneyStrategy = [new WinRabbitMoneyStrategy()];
        f_rabbit_plan.toResult(new RoundInfo());

        //反向，兔子算法
        let p_rabbit_plan = new ExcutePlan();
        p_rabbit_plan.planName = "反向兔子";
        p_rabbit_plan.recmStrategy = [new FixedStrategy({ reverse: true })]
        p_rabbit_plan.moneyStrategy = [new WinRabbitMoneyStrategy()]
        p_rabbit_plan.toResult(new RoundInfo());

        //根据自己记录胜负数投注，红色正向投注，蓝色反向投注，0不投，

        let flPlan = new ExcutePlan();
        flPlan.planName = "复利计划";
        flPlan.recmStrategy = [new FixedStrategy({ reverse: false })]
        flPlan.moneyStrategy = [new NormalGroupMoneyStrategy("")];
        flPlan.toResult(new RoundInfo());

        //this.subPlan = [f_rabbit_plan, p_rabbit_plan, normalGroupPlan];
        this.subPlan = [f_rabbit_plan, p_rabbit_plan, flPlan];
        for (let i = 0; i < 3; i++) {
            let gi = new ExcutePlan();
            gi.planName = `正向${i + 1}组`;
            gi.baseMoney = 100;
            gi.recmStrategy = [new FixedStrategy({ reverse: false })];
            gi.relationPindex = [this.subPlan.length + 1];
            gi.moneyStrategy = [new WisdomGroupMoneyStrategyV2(`$wisdom-group-${i}`, {
                groupCount: (i + 1),
                addStep: 100,
                devideStep: -100,
                reverse: false, //true:赢了+100，输了-100
                maxLevel: 3000,
            })]
            gi.toResult(new RoundInfo());
            this.subPlan.push(gi);

            let gif = new ExcutePlan();
            gif.planName = `反向${i + 1}组`;
            gif.baseMoney = 100;
            gif.relationPindex = [this.subPlan.length - 1];
            gif.recmStrategy = [new FixedStrategy({ reverse: true })];
            gif.moneyStrategy = [new WisdomGroupMoneyStrategyV2(`$reverse-wisdom-group-${i}`, {
                groupCount: (i + 1),
                addStep: 100,
                devideStep: -100,
                reverse: false, //true:赢了+100，输了-100
                maxLevel: 3000,
            })]
            gif.toResult(new RoundInfo());
            this.subPlan.push(gif);

        }

    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let zm = 0;
        let xm = 0;
        let recmV = EnumBjlResult.U;
        let recmMoney = 0;
        let sumWin = 0;
        this.subPlan.forEach((pl, index) => {
            pl.setResult(roundInfo, pl.recmInfo, pl.multiple, pl.waterRate, pl.fuliRate);
            let userRecmV = pl.toResult(roundInfo);
            let newRoundInfo: RoundInfo = Object.assign({}, roundInfo, { userRecm: userRecmV });
            pl.userRecmInfo.recmV = userRecmV;
            if (index > 1) {
                let win = pl.recmInfo.summaryInfo.winMoney - pl.recmInfo.summaryInfo.failMoney;
                sumWin += win;
            }


            if (index > 2 && index % 2 == 0) {

                let [rv, rm] = pl.toMoney(newRoundInfo, recmInfo, userRecm, pl.baseMoney);
                pl.recmInfo.preBetCount = pl.recmInfo.betCount;
                pl.recmInfo.recmV = rv;
                pl.recmInfo.recmMoney = rm;
                if (rv != EnumBjlResult.U) {
                    //pl.recmInfo.
                    pl.recmInfo.betCount++;
                }

                let giPlan = this.subPlan[index - 1] as ExcutePlan;
                let gifPlan = this.subPlan[index] as ExcutePlan;

                let giMoneyStrategy = giPlan.moneyStrategy[0] as WisdomGroupMoneyStrategyV2;
                let gifMoneyStrategy = gifPlan.moneyStrategy[0] as WisdomGroupMoneyStrategyV2;

                let giStartFlag = giMoneyStrategy && giMoneyStrategy.currentRecmMoney >= this.startLevel;
                let gifStartFlag = gifMoneyStrategy && gifMoneyStrategy.currentRecmMoney >= this.startLevel;
                //nrmMoneyStrategy.gameStart = true;
                if (giStartFlag) {
                    gifMoneyStrategy.stop();
                    gifPlan.recmInfo.recmV = EnumBjlResult.U;
                }
                else if (gifStartFlag) {
                    giMoneyStrategy.stop();
                    giPlan.recmInfo.recmV = EnumBjlResult.U;
                }

                if (giMoneyStrategy.start && !gifMoneyStrategy.start) {
                    let sum = giMoneyStrategy.getSum();
                    if (sum == 0) {
                        giPlan.resetPlan();
                        gifPlan.resetPlan();
                    }
                }
                else if (gifMoneyStrategy.start && !giMoneyStrategy.start) {
                    let sum = gifMoneyStrategy.getSum();
                    if (sum == 0) {
                        giPlan.resetPlan();
                        gifPlan.resetPlan();
                    }
                }



            }
            else {
                let [rv, rm] = pl.toMoney(newRoundInfo, recmInfo, userRecm, pl.baseMoney);
                pl.recmInfo.preBetCount = pl.recmInfo.betCount;
                pl.recmInfo.recmV = rv;
                pl.recmInfo.recmMoney = rm;
                if (rv != EnumBjlResult.U) {
                    //pl.recmInfo.
                    pl.recmInfo.betCount++;
                }
            }

        });

        if ((sumWin >= 2000 && roundInfo.changeCount > 0) || recmInfo.summaryInfo.winCount == recmInfo.summaryInfo.failCount) {
            this.subPlan.forEach((pl, index) => {
                if (index > 1) {
                    let plan = pl as ExcutePlan;
                    if (plan) plan.resetPlan();
                }
            });
        }
        else {

            this.subPlan.forEach((pl, index) => {
                pl.recmInfo.recmV = pl.recmInfo.recmV;
                pl.recmInfo.recmMoney = pl.recmInfo.recmMoney;

                if (pl.recmInfo.recmV == EnumBjlResult.Z) {
                    zm += pl.recmInfo.recmMoney;

                }
                else if (pl.recmInfo.recmV == EnumBjlResult.X) {
                    xm += pl.recmInfo.recmMoney;
                }
            });

            if (zm > xm) {
                recmV = EnumBjlResult.Z;
                recmMoney = zm - xm;
            }
            else if (xm > zm) {
                recmV = EnumBjlResult.X;
                recmMoney = xm - zm;
            }
            else {
                recmV = EnumBjlResult.U;
            }
        }


        return [recmV, recmMoney];
    }

    copyValue(valueObj: any): void {
        var obj = valueObj as WisdomMoneyStrategyV2;
        if (obj) {
            this.debugCompoenent = obj.debugCompoenent;
            this.startIndex = obj.startIndex;
            for (let i = 0; i < this.subPlan.length; i++) {
                this.subPlan[i].copyValue(obj.subPlan[i]);
            }
        }
    }
}